home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
fg
/
fgl402b
/
manuals.arj
/
USER13.DOC
< prev
next >
Wrap
Text File
|
1995-02-06
|
32KB
|
757 lines
Chapter 13
Special Effects
288 Fastgraph User's Guide
Overview
This chapter will discuss the Fastgraph routines that help produce
special visual effects. These include the ability to dissolve the screen
contents in small increments, scroll areas of the screen, change the physical
origin of the screen, and set up a split screen environment. The accompanying
example programs illustrate how to use these routines to produce some
interesting effects.
Screen Dissolving
Screen dissolving is the process of replacing the entire screen contents
in random small increments instead of all at once. Fastgraph includes two
routines, fg_fadeout and fg_fadein, for this purpose. The fg_fadeout routine
incrementally replaces the visual page contents with pixels of the current
color, while fg_fadein incrementally replaces the visual page contents with
the hidden page contents (that is, the page defined in the most recent call to
fg_sethpage). Both routines accept an integer argument that defines the delay
between each incremental replacement. A value of zero means to perform the
replacement as quickly as possible, while 1 is slightly slower, 2 is slower
yet, and so forth. The fg_fadeout and fg_fadein routines have no effect in
text video modes and always work with video pages, even if a virtual buffer is
active.
Example 13-1 shows how to use fg_fadeout. The program, which runs in any
graphics video mode, first fills the screen with a rectangle of color 2. After
waiting for a keystroke, the program incrementally replaces the screen
contents with pixels of color 15 (the current color index when fg_fadeout is
called). After another keystroke, the program exits gracefully.
Example 13-1.
#include <fastgraf.h>
void main(void);
void main()
{
int old_mode;
fg_initpm();
old_mode = fg_getmode();
fg_setmode(fg_automode());
fg_setcolor(2);
fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
fg_waitkey();
fg_setcolor(15);
fg_fadeout(0);
fg_waitkey();
fg_setmode(old_mode);
fg_reset();
}
Chapter 13: Special Effects 289
Example 13-2 shows how to use fg_fadein in any 320x200 color graphics
video mode. The program first fills the screen with a rectangle of color 2 and
then fills video page 1 with a rectangle of color 1. After waiting for a
keystroke, the program incrementally transfers the contents of page 1 to the
visual page. After the call to fg_fadein, both page 0 (the visual page) and
page 1 (the hidden page) will contain rectangles of color 1 that fill the
entire video page. Finally, the program waits for another keystroke before
returning to DOS.
Example 13-2.
#include <fastgraf.h>
#include <stdio.h>
#include <stdlib.h>
void main(void);
void main()
{
int new_mode, old_mode;
fg_initpm();
new_mode = fg_bestmode(320,200,2);
if (new_mode < 0 || new_mode == 12) {
printf("This program requires a 320 ");
printf("x 200 color graphics mode.\n");
exit(1);
}
old_mode = fg_getmode();
fg_setmode(new_mode);
fg_allocate(1);
fg_sethpage(1);
fg_setcolor(2);
fg_rect(0,319,0,199);
fg_setpage(1);
fg_setcolor(1);
fg_rect(0,319,0,199);
fg_waitkey();
fg_fadein(0);
fg_waitkey();
fg_freepage(1);
fg_setmode(old_mode);
fg_reset();
}
You also can produce some appealing visual effects by replacing the
screen contents in a non-random fashion using the fg_restore or fg_transfer
routines. For example, you could copy the hidden page contents to the visual
page through a series of concentric rectangular areas, each slightly larger
than the previous, until the entire screen is copied. Another interesting
effect is to start around the screen perimeter and proceed toward the screen
290 Fastgraph User's Guide
center, thus producing a "snake-like" effect. Experimenting with such
techniques may reveal other effects that suit your application.
Scrolling
Another useful effect is scrolling, and Fastgraph provides a routine that
performs vertical scrolling within a given region of the active video page.
The fg_scroll routine scrolls a region defined in screen space or character
space. It can scroll up or down and offers two types of scrolling: circular
and end-off. In circular scrolling, rows that scroll off one edge of the
defined region appear at its opposite edge. In end-off scrolling, such rows
simply wind up above or below the scrolling area. The following diagrams
illustrate the two types of scrolling.
end-off scrolling circular scrolling
before after before after
C B
A A
A A
B B
In these diagrams, the area bounded by the double lines is the scrolling
region, as specified in the call to fg_scroll. Also, the scrolling direction
is assumed to be down (that is, toward the bottom of the screen), and the
number of rows to scroll is the height of the area designated B. The number of
rows to scroll is often called the scrolling increment.
For the end-off scrolling example, the scrolling operation transfers
region A downward so part of it is copied into area B. The area C (which is
the same size as area B) at the top of the scrolling region is filled with
pixels of the current color index (as defined in the most recent call to
fg_setcolor), and the original contents of area B are lost. The circular
scrolling example also copies region A downward into the original area B.
Unlike end-off scrolling, however, circular scrolling preserves the area B by
copying it to the opposite edge of the scrolling region.
The fg_scroll routine takes six arguments. The first four define the
scrolling region in the order minimum x coordinate, maximum x coordinate,
minimum y coordinate, and maximum y coordinate. In graphics video modes, the x
coordinates are extended to byte boundaries if needed. The fifth argument is
the scrolling increment. It specifies the number of rows to scroll. If it is
positive, the scrolling direction is toward the bottom of the screen; if it is
negative, the scrolling direction is toward the top of the screen. The sixth
and final argument specifies the scroll type. If this value is zero, the
scroll will be circular; if it is any other value, the scroll will be end-off.
If the scroll type is circular, Fastgraph will use the hidden page (as defined
in the most recent call to fg_sethpage) as a workspace (more specifically, the
area bounded by the scrolling region extremes on the hidden page will be
used). The fg_scroll routine is disabled when a virtual buffer is active.
Chapter 13: Special Effects 291
We'll now present three example programs that use the fg_scroll routine.
Example 13-3 runs in any 320x200 graphics video mode. The program displays two
lines of text ("line one" and "line two") in the upper left corner of the
screen against a white background. It then uses fg_scroll to move the second
line down four pixel rows using an end-off scroll. After waiting for a
keystroke, the program again uses fg_scroll to move the text back to its
original position. Note especially how fg_setcolor is used before the first
call to fg_scroll to replace the "scrolled off" rows with pixels of color 15,
thus preserving the white background.
Example 13-3.
#include <fastgraf.h>
#include <stdio.h>
#include <stdlib.h>
void main(void);
void main()
{
int new_mode, old_mode;
fg_initpm();
new_mode = fg_bestmode(320,200,1);
if (new_mode < 0 || new_mode == 12) {
printf("This program requires a 320 ");
printf("x 200 color graphics mode.\n");
exit(1);
}
old_mode = fg_getmode();
fg_setmode(new_mode);
fg_setcolor(15);
fg_rect(0,319,0,199);
fg_setcolor(10);
fg_text("line one",8);
fg_locate(1,0);
fg_text("line two",8);
fg_waitkey();
fg_setcolor(15);
fg_scroll(0,63,8,15,4,1);
fg_waitkey();
fg_scroll(0,63,12,19,-4,1);
fg_waitkey();
fg_setmode(old_mode);
fg_reset();
}
Example 13-4 is similar to example 13-3, but it runs in the 80-column
color text mode (mode 3). In text modes, we cannot scroll half a character row
as in example 13-3, so the program scrolls the minimum one row instead.
Example 13-4.
292 Fastgraph User's Guide
#include <fastgraf.h>
void main(void);
void main()
{
int old_mode;
fg_initpm();
old_mode = fg_getmode();
fg_setmode(3);
fg_cursor(0);
fg_setcolor(7);
fg_rect(0,79,0,24);
fg_setattr(10,7,0);
fg_text("line one",8);
fg_locate(1,0);
fg_text("line two",8);
fg_waitkey();
fg_setcolor(7);
fg_scroll(0,7,1,1,1,1);
fg_waitkey();
fg_scroll(0,7,2,2,-1,1);
fg_waitkey();
fg_setmode(old_mode);
fg_reset();
}
Example 13-5, the final scrolling example, demonstrates a circular
scroll. The program runs in any 320x200 color graphics video mode; note the
use of video page 1 for the workspace required when fg_scroll performs a
circular scroll. The program first fills the screen with a light blue
rectangle (cyan in CGA), displays a smaller white rectangle in the center of
the screen, and then uses fg_move, fg_draw, and fg_paint to display a light
green star (magenta in CGA) within the white rectangle. The program executes a
while loop to scroll the star upward in four-pixel increments. Because the
scroll is circular, rows of the star that "scroll off" the top edge of the
white rectangle (whose height is the same as the scrolling region) reappear at
its bottom edge. The use of fg_waitfor within the loop simply slows down the
scroll. The scrolling continues until any key is pressed.
Example 13-5.
#include <conio.h>
#include <fastgraf.h>
#include <stdio.h>
#include <stdlib.h>
void main(void);
void main()
{
int new_mode, old_mode;
Chapter 13: Special Effects 293
fg_initpm();
new_mode = fg_bestmode(320,200,2);
if (new_mode < 0 || new_mode == 12) {
printf("This program requires a 320 ");
printf("x 200 color graphics mode.\n");
exit(1);
}
old_mode = fg_getmode();
fg_setmode(new_mode);
fg_allocate(1);
fg_sethpage(1);
fg_setcolor(9);
fg_rect(0,319,0,199);
fg_setcolor(15);
fg_rect(132,188,50,150);
fg_setcolor(10);
fg_move(160,67);
fg_draw(175,107);
fg_draw(140,82);
fg_draw(180,82);
fg_draw(145,107);
fg_draw(160,67);
fg_paint(160,77);
fg_paint(150,87);
fg_paint(160,87);
fg_paint(170,87);
fg_paint(155,97);
fg_paint(165,97);
while (kbhit() == 0) {
fg_waitfor(1);
fg_scroll(136,184,50,150,-4,0);
}
fg_waitkey();
fg_freepage(1);
fg_setmode(old_mode);
fg_reset();
}
Changing the Screen Origin
Fastgraph includes two routines for changing the screen origin. By
changing the screen origin, we simply mean defining the (x,y) coordinate of
the upper left corner of the display area. The fg_pan routine performs this
function in screen space, while the fg_panw routine does in world space.
Neither routine changes the graphics cursor position. Because the function of
fg_pan and fg_panw is to change the screen origin, these routines are not
applicable to virtual buffers.
294 Fastgraph User's Guide
Each of these routines has two arguments that specify the x and y
coordinates of the screen origin. For fg_pan, the arguments are integer
quantities. For fg_panw, they are floating point quantities.
In the EGA, VGA, MCGA, XVGA, and SVGA graphics modes (modes 13 to 29),
you can set the screen origin to any (x,y) coordinate position (that is, to
any pixel). In the other graphics modes, certain restrictions exist, as
imposed by specific video hardware. These constraints limit the coordinate
positions that can be used as the screen origin. Fastgraph compensates for
these restrictions by reducing the specified x and y coordinates to values
that are acceptable to the current video mode, as shown in the following
table.
x will be reduced y will be reduced
video mode to a multiple of: to a multiple of:
4-5 8 2
6 16 2
9 4 4
11 8 4
12 4 2 or 3
In modes 4 and 5, for instance, the x coordinate will be reduced to a multiple
of 8 pixels, and the y coordinate will be reduced to a multiple of 2 pixels.
In the Hercules low resolution mode (mode 12), the y coordinate reduction
depends on whether or not the specified pixel row is scan doubled.
Example 13-6 shows a useful effect that can be made with fg_pan or
fg_panw. This program uses fg_automode to select a video mode and then draws
an unfilled white rectangle. The top and bottom sides of the rectangle are
intentionally drawn just smaller than the physical screen size. After waiting
for a keystroke, the program uses a for loop to make the rectangle jiggle up
and down. The rectangle moves because fg_pan is called inside the loop to
switch the screen origin between the rectangle's upper left corner and the
original origin. Note also the use of fg_waitfor to cause slight delays after
each call to fg_pan. If we didn't use fg_waitfor, the changing of the origin
would occur so rapidly we wouldn't notice the effect. Finally, the program
restores the original video mode and screen attributes before returning to
DOS.
Example 13-6.
#include <fastgraf.h>
#include <stdio.h>
#include <stdlib.h>
void main(void);
#define DELAY 2
#define JUMP 4
void main()
{
int i;
int old_mode;
fg_initpm();
Chapter 13: Special Effects 295
old_mode = fg_getmode();
fg_setmode(fg_automode());
fg_setcolor(15);
fg_move(0,JUMP);
fg_draw(fg_getmaxx(),JUMP);
fg_draw(fg_getmaxx(),fg_getmaxy()-JUMP);
fg_draw(0,fg_getmaxy()-JUMP);
fg_draw(0,JUMP);
fg_waitkey();
for (i = 0; i < 6; i++) {
fg_pan(0,JUMP);
fg_waitfor(DELAY);
fg_pan(0,0);
fg_waitfor(DELAY);
}
fg_setmode(old_mode);
fg_reset();
}
The real power of fg_pan becomes clear when it is used with fg_resize to
perform smooth panning. Recall from Chapter 8 that fg_resize changes the video
page dimensions in native EGA and VGA graphics modes (modes 13 to 18), the
extended VGA graphics modes (20 to 23), and the SVGA graphics modes (24 to
29). We'll now present an example that shows how to use these two routines to
perform panning in the low-resolution EGA graphics mode (mode 13). The method
it uses also would work in any mode that supports video page resizing.
Example 13-7 begins by establishing the video mode and then immediately
calls fg_resize to increase the video page size to 640x400 pixels. Thus, the
video page is now four times its original size. Following this, the program
fills the page (the entire page, not just what is displayed) with a bright
green rectangle with a white border around it. It then displays the message
"Press arrow keys to pan" in the center of the 640x400 page.
The main part of the program is a loop that accepts keystrokes and calls
fg_pan to perform the panning one pixel at a time. When you press any of the
four arrow keys, the program adjusts the x and y coordinates for the screen
origin as directed. For example, pressing the up arrow key scrolls the screen
upward one pixel. When we reach the edge of the video page, the program
prevents further scrolling in that direction. This process continues until you
press the Escape key, at which time the program restores the original video
mode and screen attributes before exiting.
Example 13-7.
#include <fastgraf.h>
void main(void);
void main()
{
unsigned char key, aux;
int old_mode;
296 Fastgraph User's Guide
int x, y;
fg_initpm();
old_mode = fg_getmode();
fg_setmode(13);
fg_resize(640,400);
fg_setcolor(2);
fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
fg_setcolor(15);
fg_box(0,fg_getmaxx(),0,fg_getmaxy());
fg_justify(0,0);
fg_move(320,200);
fg_print("Press arrow keys to pan.",24);
x = 0;
y = 0;
do {
fg_getkey(&key,&aux);
if (aux == 72 && y < 200)
y++;
else if (aux == 75 && x < 320)
x++;
else if (aux == 77 && x > 0)
x--;
else if (aux == 80 && y > 0)
y--;
fg_pan(x,y);
} while (key != 27);
fg_setmode(old_mode);
fg_reset();
}
Panning With Virtual Buffers
The fg_pan routine is not suitable for panning a large image through a
small window because it affects the entire screen. However, you can achieve
this type of panning by storing the large image on an off-screen video page or
in a virtual buffer and then copy the appropriate portions of it to the fixed
window on the visual page. Example 13-8 illustrates this technique using a
virtual buffer.
Example 13-8.
#include <fastgraf.h>
void main(void);
#ifdef FG32
char buffer[64000];
#else
char huge buffer[64000];
#endif
Chapter 13: Special Effects 297
void main()
{
unsigned char key, aux;
int handle;
int old_mode;
int x, y;
fg_initpm();
old_mode = fg_getmode();
fg_setmode(19);
fg_vbinit();
handle = fg_vbdefine(buffer,320,200);
fg_vbopen(handle);
fg_loadpcx("CORAL.PCX",0);
fg_vbclose();
fg_setcolor(2);
fg_fillpage();
fg_setcolor(15);
fg_box(111,208,69,130);
fg_locate(3,8);
fg_text("Press arrow keys to pan.",24);
x = 112;
y = 129;
fg_vbpaste(x,x+95,y-59,y,112,129);
do {
fg_getkey(&key,&aux);
if (aux == 72 && y < 199)
y++;
else if (aux == 75 && x < 223)
x++;
else if (aux == 77 && x > 0)
x--;
else if (aux == 80 && y > 59)
y--;
fg_vbpaste(x,x+95,y-59,y,112,129);
} while (key != 27);
fg_setmode(old_mode);
fg_reset();
}
Example 13-8 loads our familiar CORAL.PCX image into a 320x200 virtual
buffer. It then sets up a 96x60 region in the middle of the visual page that
will serve as a window into the larger CORAL.PCX image (this region is bounded
horizontally by x=112 and x=207 and vertically by y=70 and y=129). The first
call to fg_vbpaste copies the 96x60 center portion of the virtual buffer to
the visual page window. The panning loop is similar to that of example 13-7,
except it uses fg_vbpaste to update the window contents. Pressing the arrow
keys increments or decrements the coordinates defining the source region in
298 Fastgraph User's Guide
the virtual buffer. Also, note how we've adjusted the if statements to prevent
fg_vbpaste from accessing pixels outside the virtual buffer.
Split Screen
Fastgraph provides split screen support for EGA, VGA, MCGA, and XVGA
graphics modes (modes 13 through 23) for applications running on VGA or SVGA
systems. When a split screen is enabled, the top portion of the screen (rows 0
through n-1, where n is the pixel row at which the split screen takes effect)
will contain a subset of the visual video page. The bottom portion (starting
at row n) will contain the first fg_getmaxy()-n+1 rows of video page 0. For
example, suppose we're using a 200-line graphics mode and we enable a split
screen at row 180. If page 1 is the visual video page, the first 180 lines of
the screen would be displayed from rows 0 to 179 from page 1, and the last 20
lines would be displayed from rows 0 to 19 of page 0. A split screen
environment is useful for maintaining a static image, such as a scoreboard or
status box, at the bottom of the screen while scrolling the top portion.
Example 13-9 demonstrates a typical split screen operation in the 320x200
XVGA graphics mode (mode 20). In this example, we'll assume we want to have a
status box occupying the last 20 rows (rows 180 to 199) of the screen, while
the upper 180 rows (0 to 179) will be scrolled vertically. The program begins
by setting the video mode and then calling fg_measure to compute a processor-
dependent delay value for slowing down the scrolling (this technique is
further explained in Chapter 16).
In mode 20, video memory is structured as four 320x200 physical pages.
Page 1 is not visible when we draw the blue box with the white border, so we
don't see it until call fg_setvpage to make page 1 the visual page. This of
course also makes page 0 invisible, so we don't see the 20-pixel high red
hollow box when we draw it on page 0.
Once we've drawn what we've needed on pages 0 and 1, we activate the
split screen by calling fg_split. The single parameter passed to fg_split is
the screen row at which the split screen takes effect, or put another way, the
number of rows in the top portion of the screen. In example 13-9 we call
fg_split(180), so the first 180 rows of page 1 will appear at the top of the
screen, and the first 20 rows of page 0 will appear at the bottom.
Now we're ready to scroll the upper part of the screen (which is now page
1). Fastgraph's fg_pan routine is suitable for this purpose. We achieve the
upward scrolling by incrementing the fg_pan y coordinate in a loop. We achieve
the downward scrolling by decrementing the y coordinate. We must call fg_stall
(or use another similar method) to force a brief delay between iterations. If
we didn't do this, the full 20-row scrolling would appear almost instantly,
thus losing the scrolling effect. Note that we couldn't use fg_pan to scroll
the upper part of the screen in this manner without setting up a split screen
environment. That's because by default fg_pan applies to the entire screen.
Using the split screen provides us with two independent video pages, and when
page 1 is the active video page, fg_pan doesn't touch page 0.
Example 13-9.
#include <fastgraf.h>
void main(void);
Chapter 13: Special Effects 299
void main()
{
int delay, y;
/* initialize the video environment */
fg_initpm();
fg_setmode(20);
/* define a processor-dependent panning delay */
delay = fg_measure() / 16;
/* draw a blue box with a white border on page 1 */
fg_setpage(1);
fg_setcolor(9);
fg_fillpage();
fg_setcolor(15);
fg_box(0,319,0,199);
fg_move(160,100);
fg_justify(0,0);
fg_print("This is page 1",14);
/* display what we just drew on page 1 */
fg_setvpage(1);
fg_waitkey();
/* draw a red hollow box at the top of page 0 (now invisible) */
fg_setpage(0);
fg_setcolor(12);
fg_box(0,319,0,19);
fg_setcolor(15);
fg_move(160,10);
fg_print("SPLIT SCREEN",12);
/* activate the split screen environment, making the first */
/* 20 lines of page 0 appear at the bottom of the screen, */
/* and making the first 180 lines of page 1 appear at the top */
fg_split(180);
fg_waitkey();
/* pan upward in one-line increments, displaying the rest of */
/* page 1 */
fg_setpage(1);
for (y = 0; y <= 20; y++)
{
fg_pan(0,y);
fg_stall(delay);
}
fg_waitkey();
300 Fastgraph User's Guide
/* pan back down in one-line increments to the original position */
for (y = 20; y >= 0; y--)
{
fg_pan(0,y);
fg_stall(delay);
}
fg_waitkey();
/* restore 80x25 text mode and exit */
fg_setmode(3);
fg_reset();
}
To switch from a split screen environment back to a "single page"
environment, call fg_split with a row parameter equal to the vertical screen
resolution for the current video mode.
Summary of Special Effects Routines
This section summarizes the functional descriptions of the Fastgraph
routines presented in this chapter. More detailed information about these
routines, including their arguments and return values, may be found in the
Fastgraph Reference Manual.
FG_FADEIN incrementally replaces the visual page contents with the hidden
page contents. This routine has no effect in text video modes and is not
applicable to virtual buffers.
FG_FADEOUT incrementally replaces the visual page contents with pixels of
the current color. This routine has no effect in text video modes and is not
applicable to virtual buffers.
FG_PAN changes the screen origin (the upper left corner of the screen) to
the specified screen space coordinates. This routine has no effect in text
video modes and is not applicable to virtual buffers.
FG_PANW is the world space version of the fg_pan routine.
FG_RESIZE changes the dimensions of a video page in EGA and VGA graphics
modes. This routine is disabled when a virtual buffer is active.
FG_SCROLL vertically scrolls a region of the active video page. The
scrolling may be done either up or down, using either an end-off or circular
method. Circular scrolling uses part of the hidden page as a temporary
workspace. This routine is not functional when a virtual buffer is active.
FG_SPLIT enables or disables a split screen environment in EGA, VGA,
MCGA, and XVGA graphics modes.